﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using System.Windows.Browser;

namespace Jzy.FileUpload
{
    public partial class MainPage : UserControl
    {
        private FileStream _fs = null;
        private string _filename = "";
        private int _blockSize = 1024 * 512;
        private int _blockCount;
        private string _url;
        public MainPage()
        {            
             InitializeComponent();
             _url = Application.Current.Host.Source.ToString().Replace("ClientBin/Jzy.FileUpload.xap", "") + "Common/Upload.ashx";
        }

        private void btnUpload_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                this.proUpload.Value = 0;
                OpenFileDialog dialog = new OpenFileDialog()
                {
                    Filter = "all files|*.*",
                    Multiselect = false
                };
                if ((bool)dialog.ShowDialog())
                {
                    _filename = dialog.File.Name;

                    _fs = dialog.File.OpenRead();

                    _blockCount = (int)_fs.Length / _blockSize;

                    if ((int)_fs.Length % _blockSize > 0)
                    {
                        _blockCount += 1;
                    }

                    this.proUpload.Maximum = _blockCount;
                    lblMessage.Content = "正在连接...";

                    Upload(0);
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        private void Upload(int blockIndex)
        {
            byte[] byts = new byte[_blockSize];

            if (blockIndex < _blockCount)
            {
                WebRequest request = WebRequest.Create(_url + "?filename=" + _filename + "&blockindex=" + (blockIndex + 1) + "&blockcount=" + _blockCount);
                request.Method = "POST";
                request.BeginGetRequestStream(new AsyncCallback(WriteToStream), new AsyncState() { BlockIndex = blockIndex, Request = request });

            }
        }

        private void WriteToStream(IAsyncResult result)
        {
            try
            {
                HttpWebRequest request = (result.AsyncState as AsyncState).Request as HttpWebRequest;
                int blockindex = (result.AsyncState as AsyncState).BlockIndex;
                //this.Dispatcher.BeginInvoke(new Action(delegate { this.pro.Maximum = blockcount; }));
                //this.pro.Maximum = blockindex;

                Stream stream = request.EndGetRequestStream(result);
                byte[] buffer = new byte[_blockSize];

                _fs.Seek(blockindex * this._blockSize, SeekOrigin.Begin);

                int datalength = _fs.Read(buffer, 0, buffer.Length);

                //while (datalength > 0)
                //{
                stream.Write(buffer, 0, datalength);
                //datalength = fs.Read(buffer, 0, buffer.Length);
                //index++;
                //}

                stream.Flush();
                stream.Close();

                request.BeginGetResponse(new AsyncCallback(GetResult), request);

                //this.Dispatcher.BeginInvoke(new Action(delegate() { MessageBox.Show("over"); }));

                //MessageBox.Show("over");
            }
            catch (Exception ex)
            {
                this.Dispatcher.BeginInvoke(new Action(delegate() { MessageBox.Show(ex.InnerException.Message); }));
            }
        }

        private void GetResult(IAsyncResult result)
        {
            try
            {
                HttpWebRequest request = (HttpWebRequest)result.AsyncState;

                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
                StreamReader reader = new StreamReader(response.GetResponseStream());
                int blockindex = int.Parse(reader.ReadToEnd());
                this.Dispatcher.BeginInvoke(new Action<int>(DoAction),blockindex);

                if (blockindex < _blockCount)
                {
                    Upload(blockindex);
                }


                reader.Close();
            }
            catch (Exception ex)
            {
                this.Dispatcher.BeginInvoke(new Action(delegate() { MessageBox.Show(ex.Message); }));
            }
        }

        private void DoAction(int blockIndex)
        {
            this.proUpload.Value = blockIndex;
            this.lblMessage.Content = this._filename + " " + (blockIndex * 100 / _blockCount) + "%";

            if (blockIndex == _blockCount)
            {
                //直接调用总是会提前弹出来，不知为什么。
                this.Dispatcher.BeginInvoke(new Action(delegate(){ MessageBox.Show("上传结束");}));
               
            }
        }
    }

    public class AsyncState
    {
        public int BlockIndex
        {
            get;
            set;
        }
        public WebRequest Request
        {
            get;
            set;
        }
    }
}
